/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package uk.co.dupenois.geometry;


/**
 *
 * @author mpd209
 */
public class Circle {
    private Coordinate origin;
    private double radius;
    private double area;
    private double circumference;
    public Circle(Coordinate origin, double radius){
        this.origin = origin;
        this.radius = radius;
        calcArea();
        calcCircumference();
    }

    public Circle(Coordinate point1, Coordinate point2, Coordinate point3){
        Line line1 = new Line(point1, point2, true);
        if(line1.isOnLine(point3)) throw new IllegalArgumentException("All points are in a line");
        Line line2 = new Line(point2, point3, true);

        Line line1Perp = line1.getPerpendicular(line1.getMidpoint());
        Line line2Perp = line2.getPerpendicular(line2.getMidpoint());
        
        this.origin = line1Perp.coincides(line2Perp, true);
//        if(this.origin==null){
//            System.out.println("CIRCLE: Null Origin ");
//            System.out.println("CIRCLE: point1 "+point1);
//            System.out.println("CIRCLE: point2 "+point2);
//            System.out.println("CIRCLE: point3 "+point3);
//        }
        this.radius = this.origin.getDistance(point1);
        calcArea();
        calcCircumference();
    }
    public boolean properContainsPoint(Coordinate point){
        //As opposed to just checking if one is lower than the other
        //we have to account for really stupid rounding errors, actual
        //difference has less error than squared so we use it.
//        double diff = point.getDistanceSquared(this.origin)-Math.pow(this.radius,2);
        double diffAct = point.getDistance(this.origin)-this.radius;
//        System.out.println("Difference Sq: "+diff);
//        System.out.println("Difference Actual: "+diffAct);
        return (diffAct<-0.0000000001);
    }

    public boolean containsPoint(Coordinate point){
        //Use Actual distance, squared is quciker but introduces rounding errors
        return (point.getDistance(this.origin)<=this.radius);
    }


    private void calcArea(){
        this.area = Math.PI*Math.pow(getRadius(), 2);
    }
    private void calcCircumference(){
        this.circumference = 2*Math.PI*getRadius();
    }

    /**
     * @return the origin
     */
    public Coordinate getOrigin() {
        return origin;
    }

    /**
     * @return the radius
     */
    public double getRadius() {
        return radius;
    }

    /**
     * @return the area
     */
    public double getArea() {
        return area;
    }

    /**
     * @return the circumference
     */
    public double getCircumference() {
        return circumference;
    }

    @Override
    public Circle clone(){
        return new Circle(this.origin.clone(), this.radius);
    }
}
